package com.ganmiao.server.file.service;

import com.ganmiao.exception.DefaultBusinessException;
import com.ganmiao.server.file.constant.AttachmentConstants;
import com.ganmiao.server.file.entity.GmAttachment;
import com.ganmiao.server.file.enums.GmAttachmentBizEnums;
import com.ganmiao.server.file.enums.StatusEnums;
import com.ganmiao.server.file.mapper.GmAttachmentMapper;
import com.ganmiao.server.file.repository.GmAttachmentRepository;
import com.ganmiao.server.file.util.FileFormatUtils;
import com.ganmiao.server.file.vo.GmAttachmentVo;
import com.ganmiao.server.file.vo.UploadFileVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @Author zero.yin
 * @Date 2022/8/14 2:49 PM
 * @Desc ganmiao附件服务
 */
@Slf4j
@Service
public class GmAttachmentService {

    @Value("${files.upload-path}")
    private String uploadPath;
    @Value("${files.server-path:null}")
    private String fileServerPath;

    @Value("${files.upload.doc-limit-size}")
    private Integer uploadDocLimitSize;

    @Value("${files.upload.video-limit-size}")
    private Integer uploadVideoLimitSize;

    @Autowired
    private GmAttachmentRepository gmAttachmentRepository;

    @Autowired
    private GmAttachmentMapper gmAttachmentMapper;

    /**
     * 拼接路径方法
     */
    public String splicingPath(String filePath) {
        return fileServerPath + filePath.replace(uploadPath, "");
    }


    public UploadFileVo uploadFile(MultipartFile file, HttpServletRequest request, GmAttachmentBizEnums bizEnums) {
        if (Objects.isNull(file) || file.isEmpty() || file.getSize() <= 0) {
            throw new DefaultBusinessException("上传附件不能为空！");
        }
        String fileName = file.getOriginalFilename();
        assert fileName != null;
        String format = fileName.substring(fileName.lastIndexOf(".") + 1);
        GmAttachment gmAttachment = null;
        if (FileFormatUtils.isVideoFile(format)) {
            gmAttachment = this.uploadVideoFileInner(file, request, bizEnums);
        } else if (FileFormatUtils.isDocFile(format)) {
            gmAttachment = this.uploadDocFile(file, request, bizEnums);
        } else if (FileFormatUtils.isPicFile(format)) {
            gmAttachment = this.uploadDocFile(file, request, bizEnums);
        } else {
            throw new DefaultBusinessException(String.format("附件格式[%s]不支持，请联系管理员！", format));
        }

        gmAttachment.setStatus(StatusEnums.NORMAL.getStatus());
        gmAttachment.setFileName(fileName);
        gmAttachment.setBizType(bizEnums.getBizType());
        gmAttachment.setFormat(format);
        gmAttachment.setKkpreviewFlag('0');
        gmAttachment.setOfficeKey(UUID.randomUUID().toString() + "_" + UUID.randomUUID().toString());
        gmAttachmentRepository.save(gmAttachment);

        UploadFileVo uploadFileVo = new UploadFileVo();
        BeanUtils.copyProperties(gmAttachment, uploadFileVo);
        //绝对路径
        uploadFileVo.setAbsoluteFileUrl(gmAttachment.getFileUrl());

        //文档类型加入http拼接
        if (StringUtils.isNotEmpty(uploadFileVo.getFileUrl())) {
            uploadFileVo.setFileUrl(fileServerPath + uploadFileVo.getFileUrl());
        }

        return uploadFileVo;
    }

    /**
     * 上传文档附件（内部文件服务器）
     *
     * @param file
     * @param request
     * @param bizEnums
     * @return
     */
    public GmAttachment uploadDocFile(MultipartFile file, HttpServletRequest request, GmAttachmentBizEnums bizEnums) {
        if (file.getSize() > (uploadDocLimitSize * 1024 * 1024)) {
            throw new DefaultBusinessException("上传文档/图片不能大于" + uploadDocLimitSize + "MB");
        }
        File folder = new File(uploadPath + bizEnums.getBizType());
        if (!folder.isDirectory()) {
            if (!folder.mkdirs()) {
                throw new DefaultBusinessException("文件夹创建失败! folder=" + folder.getName());
            }
        }

        String fileName = file.getOriginalFilename();
        String fileUrl = "";
        assert fileName != null;
        String newName = UUID.randomUUID().toString() + fileName.substring(fileName.lastIndexOf("."));
        try {
            file.transferTo(new File(folder, newName));
            //这里的/files/ 对应的就是你在WebMvcConfig设置的地址映射
            String serverPath = "";
            if (StringUtils.isEmpty(fileServerPath)) {
                serverPath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/files/";
            }
            fileUrl = serverPath + bizEnums.getBizType() + "/" + newName;
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }

        return GmAttachment.builder()
                .transferStatus(AttachmentConstants.transfer_done)
                .fileStore(AttachmentConstants.file_store_gm)
                .fileUrl(fileUrl)
                .build();
    }

    /**
     * 上传视频/音频附件（内部服务器）
     *
     * @param file
     * @return
     */
    private GmAttachment uploadVideoFileInner(MultipartFile file, HttpServletRequest request, GmAttachmentBizEnums bizEnums) {
        if (file.getSize() > (uploadVideoLimitSize * 1024 * 1024)) {
            throw new DefaultBusinessException("上传视频资源不能大于" + uploadVideoLimitSize + "MB");
        }
        File folder = new File(uploadPath + bizEnums.getBizType());
        if (!folder.isDirectory()) {
            if (!folder.mkdirs()) {
                throw new DefaultBusinessException("文件夹创建失败! folder=" + folder.getName());
            }
        }

        String fileName = file.getOriginalFilename();
        String fileUrl = "";
        assert fileName != null;
        String newName = UUID.randomUUID().toString() + fileName.substring(fileName.lastIndexOf("."));
        try {
            file.transferTo(new File(folder, newName));
            //这里的/files/ 对应的就是你在WebMvcConfig设置的地址映射
            String serverPath = "";
            if (StringUtils.isEmpty(fileServerPath)) {
                serverPath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/files/";
            }
            fileUrl = serverPath + bizEnums.getBizType() + "/" + newName;
        } catch (IOException e) {
            e.printStackTrace();
        }


        return GmAttachment.builder()
                .transferStatus(AttachmentConstants.transfer_done)
                .fileStore(AttachmentConstants.file_store_gm)
                .fileUrl(fileUrl)
                .build();
    }

    /**
     * 查询单个文件
     *
     * @param fileId
     * @return
     */
    public GmAttachmentVo getByFileId(Integer fileId) {
        if (Objects.nonNull(fileId)) {
            GmAttachment gmAttachment = gmAttachmentRepository.getById(fileId);
//            if (gmAttachment.getTransferStatus() == '0') {
//                throw new DefaultBusinessException("资源还未转码成功,请稍后再试", ResponseCode.FAIL);
//            }
            if (Objects.nonNull(gmAttachment)) {
                return this.convertGmAttachmentVo(gmAttachment);
            }
        }

        return null;
    }

    /**
     * 不校验转码状态
     *
     * @param fileId
     * @return
     */
    public GmAttachmentVo getByFileIdV2(Integer fileId) {
        if (Objects.nonNull(fileId)) {
            GmAttachment gmAttachment = gmAttachmentRepository.getById(fileId);
            if (Objects.nonNull(gmAttachment)) {
                return this.convertGmAttachmentVo(gmAttachment);
            }
        }

        return null;
    }

    public List<GmAttachmentVo> getByIds(List<Integer> fileIds) {
        List<GmAttachmentVo> voList = null;
        if (!CollectionUtils.isEmpty(fileIds)) {
            List<GmAttachment> attachmentInfoList = gmAttachmentRepository.listByIds(fileIds);
            if (!CollectionUtils.isEmpty(attachmentInfoList)) {
                voList = attachmentInfoList.stream().map(item -> {
                    return this.convertGmAttachmentVo(item);
                }).collect(Collectors.toList());
            }
        }

        return voList;
    }


    private GmAttachmentVo convertGmAttachmentVo(GmAttachment gmAttachment) {
        if (StringUtils.isEmpty(gmAttachment.getOfficeKey())) {
            gmAttachment.setOfficeKey(UUID.randomUUID().toString() + "_" + gmAttachment.getFileId());
            gmAttachmentRepository.updateById(gmAttachment);
        }

        GmAttachmentVo vo = new GmAttachmentVo();
        //拼接http路径
        BeanUtils.copyProperties(gmAttachment, vo);
        vo.setFileUrl(splicingPath(vo.getFileUrl()));
//        if (Objects.nonNull(gmAttachment.getVideoId())) {
//            try {
//                VideoInfoDto videoInfoDto = videoService.getVideoUrl(gmAttachment.getVideoId());
//                vo.setDuration(videoInfoDto.getDuration());
//                vo.setFileUrl(HttpReplaceUtil.replaceHttp(videoInfoDto.getVideoUrl()));
//                vo.setPlayerToken(videoService.getPlayerToken(gmAttachment.getVideoId()));
//            } catch (Exception e) {
//                log.error(e.getMessage());
//            }
//        }

        return vo;
    }

    /**
     * 保存文档资源
     *
     * @param gmAttachment
     * @return
     */
    public GmAttachment saveAttachmentDocumentation(GmAttachment gmAttachment) {
        //加入附件表
        gmAttachment.setFileStore('1');
        gmAttachment.setStatus('1');
        gmAttachment.setTransferStatus('1');
        gmAttachment.setKkpreviewFlag('0');
        gmAttachmentRepository.save(gmAttachment);

        return gmAttachment;
    }

}
